#! /bin/sh /usr/share/dpatch/dpatch-run
## fix_integer_overflows.dpatch by Mehdi Dogguy <dogguy@pps.jussieu.fr>
##
## DP: Fix multiple integer overflows.
## DP: http://www.ocert.org/advisories/ocert-2009-009.html

@DPATCH@
diff -urNad camlimages-2.20~/png/pngread.c camlimages-2.20/png/pngread.c
--- camlimages-2.20~/png/pngread.c	2002-03-26 14:15:10.000000000 +0100
+++ camlimages-2.20/png/pngread.c	2009-07-07 13:58:45.639592173 +0200
@@ -13,6 +13,8 @@
 /***********************************************************************/
 #include <config.h>
 
+#include <limits.h>
+
 #if HAVE_PNG
 #include <png.h>
 #endif
@@ -33,6 +35,12 @@
 #define PNG_TAG_INDEX16 2
 #define PNG_TAG_INDEX4 3
 
+/* Test if x or y are negative, or if multiplying x * y would cause an
+ * arithmetic overflow.
+ */
+#define oversized(x, y)						\
+  ((x) < 0 || (y) < 0 || ((y) != 0 && (x) > INT_MAX / (y)))
+
 value read_png_file_as_rgb24( name )
      value name;
 {
@@ -88,6 +96,9 @@
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
 	       &interlace_type, NULL, NULL);
 
+  if (oversized (width, height))
+    failwith ("png error: image contains oversized or bogus width and height");
+
   if ( color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) { 
     png_set_gray_to_rgb(png_ptr); 
@@ -109,10 +120,16 @@
 
   rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
+  if (oversized (rowbytes, height))
+    failwith ("png error: image contains oversized or bogus rowbytes and height");
+
   {
     int i;
     png_bytep *row_pointers;
 
+    if (oversized (sizeof (png_bytep), height))
+      failwith ("png error: image contains oversized or bogus height");
+
     row_pointers = (png_bytep*) stat_alloc(sizeof(png_bytep) * height);
 
     res = alloc_tuple(3);
@@ -242,6 +259,9 @@
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
 	       &interlace_type, NULL, NULL);
 
+  if (oversized (width, height))
+    failwith ("png error: image contains oversized or bogus width and height");
+
   if ( color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) { 
     png_set_gray_to_rgb(png_ptr); 
@@ -258,6 +278,9 @@
 
   rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
+  if (oversized (rowbytes, height))
+    failwith ("png error: image contains oversized or bogus rowbytes and height");
+
 /*
 fprintf(stderr, "pngread.c: actual loading\n"); fflush(stderr);
 */
@@ -266,6 +289,9 @@
     png_bytep *row_pointers;
     char mesg[256];
  
+    if (oversized (sizeof (png_bytep), height))
+      failwith ("png error: image contains oversized or bogus height");
+
     row_pointers = (png_bytep*)stat_alloc(sizeof(png_bytep) * height);
     res = alloc_tuple(3);
 
--- ../old/camlimages-2.2.0/gif/gifread.c	2004-09-21 23:56:41.000000000 +0200
+++ camlimages-2.2.0/gif/gifread.c	2009-08-08 09:30:48.000000000 +0200
@@ -20,6 +20,15 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <limits.h>
+
+/* Test if x or y are negative, or if multiplying x * y would cause an
+ * arithmetic overflow.
+ */
+#define oversized(x, y)                                                \
+  ((x) < 0 || (y) < 0 || ((y) != 0 && (x) > INT_MAX / (y)))
+
+
 #define gif_not_supported() \
   failwith( "gif is not supported" ); \
   return(Val_unit)
@@ -193,6 +202,10 @@
   CAMLlocal1(buf);
 
   GifFileType *GifFile = (GifFileType*) hdl;
+ 
+  if( oversized( GifFile->Image.Width, sizeof(GifPixelType) ) ){
+    failwith ("gif error: image contains oversized or bogus width and height");
+  }
 
   buf = alloc_string( GifFile->Image.Width * sizeof(GifPixelType) ); 
 
--- ../old/camlimages-2.2.0/jpeg/jpegread.c	2002-04-09 13:00:11.000000000 +0200
+++ camlimages-2.2.0/jpeg/jpegread.c	2009-08-08 09:34:26.000000000 +0200
@@ -26,6 +26,14 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <limits.h>
+
+/* Test if x or y are negative, or if multiplying x * y would cause an
+ * arithmetic overflow.
+ */
+#define oversized(x, y)                                                \
+  ((x) < 0 || (y) < 0 || ((y) != 0 && (x) > INT_MAX / (y)))
+
 /*
  * Include file for users of JPEG library.
  * You will need to have included system headers that define at least
@@ -159,6 +167,12 @@
    */ 
   /* JSAMPLEs per row in output buffer */
 
+  if( oversized(cinfo.output_width, cinfo.output_components) ){
+    jpeg_destroy_decompress(&cinfo);
+    fclose(infile);
+    failwith ("jpeg error: image contains oversized or bogus width and height");
+  }
+
   row_stride = cinfo.output_width * cinfo.output_components;
 
   /* Make a one-row-high sample array that will go away when done with image */
